﻿using Newtonsoft.Json;
using Station.Inspect.UI;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Vision.Common
{
    /// <summary>
    /// 库元件
    /// </summary>
    public class NodeElement : CDrawRect
    {
        public int ID = 0;
        public string Name { get => lib != null ? lib.Name : $"空元件{ID}"; }
        [JsonIgnore]
        public Bitmap Image { get; set; }
        [JsonIgnore]
        public bool IsOK { get; set; } = true;

        private int libID=-1;
        public int LibID { get => libID; set => libID=value; }
        private NodeLib lib;    //元件库
        [JsonIgnore]
        public NodeLib Lib
        {
            get => lib;
            set
            {
                if (lib != value)
                {
                    NodeLib oldLib = lib;
                    lib = value;
                    libID = -1;
                    if (oldLib != null)
                        oldLib.Dettatch(this);
                    if (lib != null)
                        lib.Attatch(this);
                }
                if (lib != null)
                {
                    libID = lib.ID;
                    BaseAngle = lib.Angle;
                    this.Size = lib.size;
                    this.Angle = lib.Angle;
                }
            }
        }
        //private NodeComponent compnt;
        
        [JsonIgnore]
        //public NodeComponent Compnt
        //{
        //    get => compnt;
        //    set => compnt=value;
        //}
        //private PointF baseStartPoint;
        public PointF BaseStartPoint { get; set; } = new PointF(0,0);
        public float BaseAngle { get; set; } = 0;

        public NodeElement() { }
        public NodeElement(int ID,PointF startPt ,NodeLib lib)
        {
            this.ID = ID;
            this.StartPoint = startPt;
            this.lib = lib;
            this.Size = lib.size;
            this.Angle = lib.Angle;
        }

        public void Reset(bool bBase2Cur = true)
        {
            if(bBase2Cur)
            {
                StartPoint = BaseStartPoint;
                Angle = BaseAngle;
            }
            else
            {
                BaseStartPoint = StartPoint;
                BaseAngle = Angle;
            }
        }


        //public string FullName { get=> }
        public new NodeElement Copy()
        {
            NodeElement node = new NodeElement();
            CopyTo(node);
            return node;
        }
       
        public void CopyTo(NodeElement node)
        {
            base.CopyTo(node);
            node.ID = ID;
            node.Lib = Lib;
            //node.Name = Name;
            node.Image = Image;
        }
        public override void ReadSelfAttrbutes(XmlReader reader)
        {
            //if (GlobalSysVar.PrjVersion < 1)
            //    ReadPrjV0(reader);
            //else
                ReadPrjV1(reader);
        }
        private void ReadPrjV0(XmlReader reader)
        {
            base.ReadSelfAttrbutes(reader);
#if USE_CMP_V2
            float x = Convert.ToSingle(reader.GetAttribute("X"));
            float y = Convert.ToSingle(reader.GetAttribute("Y"));
            float width = Convert.ToSingle(reader.GetAttribute("Width"));
            float height = Convert.ToSingle(reader.GetAttribute("Height"));
            BaseAngle = Convert.ToSingle(reader.GetAttribute("Angle"));
            BaseStartPoint = new PointF(x, y);
            Size = new SizeF(width, height);
            StartPoint = BaseStartPoint;
            Angle = BaseAngle;
#endif
            lib = null;
            string name = reader.GetAttribute("Name");
            ID = Convert.ToInt32(name.Substring(2, name.Length - 2));
        }
        private void ReadPrjV1(XmlReader reader)
        {
            base.ReadSelfAttrbutes(reader);
#if USE_CMP_V2
            float x = Convert.ToSingle(reader.GetAttribute("X"));
            float y = Convert.ToSingle(reader.GetAttribute("Y"));
            float width = Convert.ToSingle(reader.GetAttribute("Width"));
            float height = Convert.ToSingle(reader.GetAttribute("Height"));
            BaseAngle = Convert.ToSingle(reader.GetAttribute("Angle"));
            BaseStartPoint = new PointF(x, y);
            Size = new SizeF(width, height);
            StartPoint = BaseStartPoint;
            Angle = BaseAngle;
#endif
            string strLibID = reader.GetAttribute("libID");
            if(!string.IsNullOrEmpty(strLibID))
            {
                int libID = Convert.ToInt32(strLibID);
                Lib = NodeLibManager.Find(libID);
            }
            ID = Convert.ToInt32(reader.GetAttribute("ID"));
        }
        //V0
        //public override void WriteSelfAttrbutes(XmlWriter writer)
        //{
        //    base.WriteSelfAttrbutes(writer);
        //    writer.WriteAttributeString("Name", Name);
        //}
        //V1
        public override void WriteSelfAttrbutes(XmlWriter writer)
        {
            base.WriteSelfAttrbutes(writer);
#if USE_CMP_V2
            writer.WriteAttributeString("X", BaseStartPoint.X.ToString());
            writer.WriteAttributeString("Y", BaseStartPoint.Y.ToString());
            writer.WriteAttributeString("Width", Size.Width.ToString());
            writer.WriteAttributeString("Height", Size.Height.ToString());
            writer.WriteAttributeString("Angle", BaseAngle.ToString());//
#endif
            writer.WriteAttributeString("libID", lib?.ID.ToString());
            writer.WriteAttributeString("ID", ID.ToString());
        }
        static protected Pen CellPen { get; set; } = new Pen(Color.Yellow, 2) { DashStyle = DashStyle.Dash };//边框颜色
        //绘制
        public override void Draw(Graphics g, float scale = 1)
        {
            if (m_visible == false)
                return;
            int startX = 0;
            int startY = 0;
            Rectangle rectangle = new Rectangle(startX, startY, (int)size.Width, (int)size.Height);
            if (scale > 1)
                scale = 1;
            Pen curPen = State == TrackerState.normal ? BorderPen : BorderPenSelected;
            SolidBrush solidBrush = State == TrackerState.normal ? FillBrush : FillBrushSelected;
            float crossWidth = Math.Min(size.Width / 2, 5 / scale);
            float crossHeight = Math.Min(size.Height / 2, 5 / scale);
            Matrix oldM = g.Transform;
            g.TranslateTransform(startPoint.X, startPoint.Y);
            if (Math.Abs(angle) > float.Epsilon)
                g.RotateTransform((float)angle);

            g.FillRectangle(solidBrush, rectangle);
            if (Lib != null)
            {
                foreach (var cell in Lib.NodeCells)
                {
                    Rectangle rect = new Rectangle((int)cell.StartPoint.X, (int)cell.StartPoint.Y, (int)cell.Size.Width, (int)cell.Size.Height);
                    int cx = (rect.Left + rect.Right) / 2;
                    int cy = (rect.Top + rect.Bottom) / 2;
                    g.DrawLine(CellPen, cx - crossWidth, cy, cx + crossWidth, cy);
                    g.DrawLine(CellPen, cx, cy - crossHeight, cx, cy + crossHeight);
                    g.DrawRectangle(CellPen, rect);
                }
            }

            g.DrawLine(curPen, size.Width / 2 - crossWidth, size.Height / 2, size.Width / 2 + crossWidth, size.Height / 2);
            g.DrawLine(curPen, size.Width / 2, size.Height / 2 - crossHeight, size.Width / 2, size.Height / 2 + crossHeight);
            g.DrawRectangle(curPen, rectangle);
            if (State == TrackerState.active)//选中
            {

                float cursize = 7 / scale;
                float dx = cursize / 2;
                float x1 = startX - dx;
                float x2 = startX + size.Width / 2 - dx;
                float x3 = startX + size.Width - dx;
                float y1 = startY - dx;
                float y2 = startY + size.Height / 2 - dx;
                float y3 = startY + size.Height - dx;

                g.FillRectangle(BorderBrush, x1, y1, cursize, cursize);   //左上
                g.FillRectangle(BorderBrush, x2, y1, cursize, cursize);  //上
                g.FillRectangle(BorderBrush, x3, y1, cursize, cursize);  //右上

                g.FillRectangle(BorderBrush, x1, y2, cursize, cursize);  //左中
                g.FillRectangle(BorderBrush, x3, y2, cursize, cursize);  //右中

                g.FillRectangle(BorderBrush, x1, y3, cursize, cursize);   //左下
                g.FillRectangle(BorderBrush, x2, y3, cursize, cursize);  //下
                g.FillRectangle(BorderBrush, x3, y3, cursize, cursize);  //右下
            }
            
            
            g.Transform = oldM;

            //int startX = -m_size.Width / 2;
            //int startY = -m_size.Height / 2;
            //Rectangle rectangle = new Rectangle(new Point(startX,startY), m_size);
            //int width = Math.Min(m_size.Width / 2, 5);
            //int height = Math.Min(m_size.Height / 2, 5);
            //g.RotateTransform((float)m_angle);
            //g.TranslateTransform(m_center.X, m_center.Y);

            //g.FillRectangle(FillBrush, rectangle);
            //g.DrawLine(BorderPen, -width, 0, +width, 0);
            //g.DrawLine(BorderPen, 0,- height, 0, + height);
            //g.DrawRectangle(BorderPen, rectangle);
            //if(State == TrackerState.selected)//选中
            //{
            //    g.FillRectangle(BorderBrush, startX-2, startY-2,5,5);   //左上
            //    g.FillRectangle(BorderBrush, startX+m_size.Width/2 - 2, startY - 2, 5, 5);  //上
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY - 2, 5, 5);  //右上

            //    g.FillRectangle(BorderBrush, startX - 2, startY + m_size.Height/2 - 2, 5, 5);  //左中
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY + m_size.Height / 2 - 2, 5, 5);  //右中

            //    g.FillRectangle(BorderBrush, startX - 2, startY+m_size.Height - 2, 5, 5);   //左下
            //    g.FillRectangle(BorderBrush, startX + m_size.Width / 2 - 2, startY + m_size.Height - 2, 5, 5);  //下
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY + m_size.Height - 2, 5, 5);  //右下

            //}

            //g.ResetTransform();
            //g.RotateTransform(-(float)m_angle);
            //g.TranslateTransform(-ptCenter.X, -ptCenter.Y);
            //g.DrawLine(BorderPen, m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2 - 5, m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2 + 5);

            //g.EndContainer();
        }
    }
}
